import 'package:dio/dio.dart';
import 'package:flutter_first_project/constant/index.dart';
import 'package:flutter_first_project/utils/Emitter.dart';
import 'package:flutter_first_project/utils/TokenManager.dart';
import 'package:flutter_first_project/utils/toast.dart';

class RequestDio{
  // 创建dio实例
 final Dio _dio = Dio();
  RequestDio(){
    // 配置基地址，响应时间
  //    _dio.options.connectTimeout = const Duration(seconds: GlobalVariable.timeout);
  // _dio.options.receiveTimeout = const Duration(seconds: GlobalVariable.timeout);
      // 配置基地址，响应时间
      _dio.options.baseUrl = GlobalVariable.baseUrl;
       _dio
       .options.connectTimeout = const Duration(seconds: GlobalVariable.timeout);
      _dio.options.receiveTimeout = const Duration(seconds: GlobalVariable.timeout);
    _configInterceptors();  
  }

// 刷新token
 Future<bool> _refreshToken() async{
    try{
      String refreshToken = tokenManager.getRefreshToken();
      Dio dio = Dio(); 
      var res = await dio.post('${GlobalVariable.baseUrl}/refreshToken',
      options:
      Options(headers: {"Authorization": "Bearer $refreshToken"})
      );
      if(res.data['code'] == 10000){
        // 说明请求成功
        tokenManager.setToken(res.data['data']['token'],refreshToken: res.data['data']['refreshToken']);
        return true;
      }
      else{
        return false;
      }
    }catch(e){
        return false;
    }
 }


// 上传头像接口
 Future upload(String url, {FormData? data}) async{
  final result = await _dio.post(url,data: data);
  // 需要对数据进行二次处理
  return _handleResult(result);
 }

// 封装get请求
 Future get(String url, {Map<String,dynamic>? params}) async{
    final res = await _dio.get(url,queryParameters: params);
    // return res.data;
    return _handleResult(res);
  }
  // 封装post请求
 Future post(String url, {Map<String,dynamic>? data}) async{
    final res = await _dio.post(url,data: data);
    // return res.data;
    return _handleResult(res);
  }
  // 封装put请求
 Future put(String url, {Map<String,dynamic>? data}) async{
    final res = await _dio.put(url,data: data);
    // return res.data;
    return _handleResult(res);
  }
  // 封装delete请求
 Future delete(String url, {Map<String,dynamic>? data}) async{
    final res = await _dio.delete(url,data: data);
    // return res.data;
    return _handleResult(res);
  }
  // 统一处理返回结果
  _handleResult(response){
      if(response.data['code'] == 10000){
        return response.data['data'];
      }
      else{
             // 提示用户
        PrompAction.showFales(response.data['message']);
        // 抛出异常
        throw Exception(response.data['message']);
   
      }
  }
  

  // 配置响应和请求拦截器
   _configInterceptors(){
   _dio.interceptors.add(
  InterceptorsWrapper(
    // 请求拦截器
    onRequest: (RequestOptions options, RequestInterceptorHandler handler) {
      // 在请求发送之前做某些操作。
    // 如果你想用自定义的数据来响应这个请求，
    // 可以使用 `handler.resolve(response)` 来解析一个 `Response` 对象。
     // 如果你想终止请求并触发一个错误， 可以使用 `handler.reject(dioError)` 来抛出一个 `DioException` 异常。
    //  注入token
    var  token = tokenManager.getToken();
    // 如果token为空，则不注入token
    if(token!=''){
      options.headers['Authorization'] = 'Bearer $token';
    }
      return handler.next(options);
    },
    // 响应拦截器
    onResponse: (Response response, ResponseInterceptorHandler handler) {
  // 对响应数据进行一些操作。
// 如果你终止请求并触发一个错误，可以使用 `handler.reject(dioError)` 来拒绝一个 `DioException` 对象。
    // 如果请求成功，即状态码大于200小于300,返回响应数据，如果失败则提示用户，并返回错误信息
    if(response.statusCode! >= 200 && response.statusCode! < 300){
      return handler.next(response);
    }else{
      // 错误信息4开头：客户端如请求错误，5开头是服务器错误
      // 401 是token失效
      PrompAction.showFales(response.statusMessage!); // 提示用户
      // 抛出异常 返回一个错误的flutter
      return handler.reject(DioException( requestOptions: response.requestOptions));
    }   
    },
    onError: (DioException error, ErrorInterceptorHandler handler)async {
 // 对响应错误进行一些处理。
// 如果你想用一些自定义数据来完成这个请求，
// 可以使用 `handler.resolve(response)` 来解析一个 `Response` 对象。
// 401token失效
      if(error.response?.statusCode == 401){
        String refreshToken = tokenManager.getRefreshToken();
        if(refreshToken.isNotEmpty){
          // 换token的方法
          bool IsOk = await _refreshToken();
          if(IsOk){
            // 此时说明token已经换成功了
            // 之前的请求失败把之前的请求重新发送
            return handler.resolve(await _dio.fetch(error.requestOptions));
          }
          else{
               // 彻底活不了
            tokenManager.deleteToken(); // 清除token,跳转到登录页
            eventBus.fire(LogoutEvent());
          }
        }
        // 清除token，跳转到登录页
        tokenManager.deleteToken();
        eventBus.fire(LogoutEvent());
      }
      return handler.next(error);
    },
  ),
);
  }
}
final requestDio = RequestDio();